#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <assert.h>

// void handler(int signo)
// {
//     std::cout << "child quit, father get a signo: " << signo << std::endl;
// }

// void CleanupChild(int signo)
// {
//     // v1，只回收了一个，如果同时退出的进程很多，由于在处理的时候信号被屏蔽了，所以会有一些不会被回收
//     // if (signo == SIGCHLD)
//     // {
//     //     pid_t rid = waitpid(-1, nullptr, 0);
//     //     if (rid > 0)
//     //     {
//     //         std::cout << "wait child success: " << rid << std::endl;
//     //     }
//     // }
//     // std::cout << "wait sub process done" << std::endl;
//     // v2	如果同时退出的进程很多，由于在处理的时候信号被屏蔽了，所以会有一些不会被回收
//     // if (signo == SIGCHLD)
//     // {
//     //     while (true)
//     //     {
//     //         pid_t rid = waitpid(-1, nullptr, 0); // -1 : 回收任意一个子进程
//     //         if (rid > 0)
//     //         {
//     //             std::cout << "wait child success: " << rid << std::endl;
//     //         }
//     //         else if(rid <= 0) break;
//     //     }
//     // }
//     // std::cout << "wait sub process done" << std::endl;
//     // v3
//     if (signo == SIGCHLD)
//     {
//         while (true)
//         {
//             pid_t rid = waitpid(-1, nullptr, WNOHANG); // -1 : 回收任意一个子进程，WNOHANG没有孩子离开立即返回
//             if (rid > 0)
//             {
//                 std::cout << "wait child success: " << rid << std::endl;
//             }
//             else if (rid <= 0)
//                 break;
//         }
//     }
//     std::cout << "wait sub process done" << std::endl;
// }

//SIGCHLD,子进程退出要进行回收，父进程会收到这个信号进行处理

int main()
{
    //signal(SIGCHLD, handler);
    signal(SIGCHLD, SIG_IGN);		//特例：仅在Linux上会进行自动回收，在其他系统上不保证

    // 50个退出，50个没有
    for (int i = 0; i < 100; i++)
    {
        pid_t id = fork();
        if (id == 0)
        {
            // child
            int cnt = 5;
            while (cnt--)
            {
                std::cout << "I am child process: " << getpid() << std::endl;
                sleep(1);
            }
            std::cout << "child process died" << std::endl;
            exit(0);
        }
    }

    // father
    // while (true)
    //     sleep(1);
}

// void Print(sigset_t &pending)
// {
//     std::cout << "curr process pending: ";
//     for(int sig = 31; sig >= 1; sig--)
//     {
//         if(sigismember(&pending, sig)) std::cout << "1";
//         else std::cout << "0";
//     }
//     std::cout << "\n";
// }

// void handler(int signum)
// {
// 	 std::cout << "signal : " << signum << std::endl;
//     // 不断获取当前进程的pending信号集合并打印
//     sigset_t pending;
//     sigemptyset(&pending);
//     while(true)
//     {
//         sigpending(&pending);
//         Print(pending);
//         sleep(1);
// 	}
// }

// int main()
// {
// 	struct sigaction act ,oact;
// 	act.sa_handler = handler;
// 	act.sa_flags = 0;
// 	//sa_mask当某个信号的处理函数被调用时，内核自动将当前信号加入进程的信号屏蔽字当中
// 	//在调用信号处理函数时，除了当前信号被自动屏蔽之外，还希望自动屏蔽另外一些信号，则用sa_mask字段说明
// 	sigemptyset(&act.sa_mask);	
// 	//sigaddset(&act.sa_mask,2);
// 	sigaddset(&act.sa_mask,3);
// 	sigaddset(&act.sa_mask,4);
// 	sigaddset(&act.sa_mask,5);
// 	std::cout<<"pid: "<<getpid()<<std::endl;
// 	sigaction(2,&act,&oact);

// 	while(true) sleep(1);

// 	return 0;
// }